package ink.metoo.auto.fishpi

import com.google.gson.Gson
import ink.metoo.auto.fishpi.call.UserCall
import ink.metoo.auto.fishpi.chatroom.ChatRooms
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
import kotlin.io.path.Path
import kotlin.system.exitProcess

object ClientCaches {

    private val userDir = System.getProperty("user.home")!!

    @Suppress("MemberVisibilityCanBePrivate")
    val baseDir = "${userDir}/.auto-fishpi-active"

    private var defaultCache = ClientCache(baseDir)

    var liveness: Double
        get() = defaultCache.liveness
        set(value) {
            defaultCache.liveness = value
        }

    val apiKey: String
        get() = defaultCache.apiKey

    var everydayState: EverydayState
        get() = defaultCache.everydayState
        set(value) {
            defaultCache.everydayState = value
        }

    fun refreshEverydayState(block: (EverydayState) -> Unit) {
        val eds = everydayState
        block(eds)
        everydayState = eds
    }


    fun refresh() {
        val dir = defaultCache.keyFile
        if (dir.exists()) {
            dir.delete()
        }
        defaultCache = ClientCache(baseDir)
        liveness = -1.0
        Log.info("refresh apiKey")
        ChatRooms.refresh()
    }

}

/**
 * 每日状态记录
 */
class EverydayState {

    var commentCount: Int = 0

    /**
     * 已发送过的消息
     */
    val sentMessages: MutableList<String> = mutableListOf()

}

class ClientCache(private val baseDir: String, val username: String = Settings.fishpiClient.username) {

    var liveness: Double = -1.0

    val keyFile: File = Path("${baseDir}/cache/${username}.key").toFile()

    val apiKey: String by lazy {
        Log.info("login user: $username")
        if (keyFile.exists()) {
            val readText = keyFile.readText()
            Log.info("read cache key $keyFile {$readText}")
            return@lazy readText
        }
        keyFile.parentFile.mkdirs()
        UserCall.getKey().run {
            val key = key ?: throw RuntimeException(msg?.let {
                if (it == "密码错误" || it == "登录频率过快，请5分钟后重试。") {
                    Log.error(username + msg)
                    exitProcess(0)
                } else "get api-key fail cause: $it"
            } ?: "get key fail")
            Log.info("request key {$key}")
            keyFile.writeText(key)
            Log.info("save cache key to $keyFile")
            key
        }
    }

    private val stateFile: File
        get() = Path("${baseDir}/everyday/${username}/${dateFormat.format(Date())}.json").toFile()

    var everydayState: EverydayState
        get() {
            val stateFile = stateFile
            if (stateFile.exists()) {
                try {
                    return gson.fromJson(stateFile.reader(), EverydayState::class.java)
                } catch (e: Exception) {
                    Log.error(e.message, e)
                }
            } else {
                stateFile.parentFile.let {
                    it.exists() || it.mkdirs()
                }
            }
            return EverydayState()
        }
        set(value) {
            val stateFile = stateFile
            stateFile.parentFile.let {
                it.exists() || it.mkdirs()
            }
            stateFile.exists() || stateFile.createNewFile()
            stateFile.writeText(gson.toJson(value))
        }

    companion object {
        private val dateFormat = SimpleDateFormat("yyyy-MM-dd")
        private val gson = Gson()
    }

}